package com.changdu.seatunnel.admin.util;

import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.StringTokenizer;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import jakarta.servlet.http.HttpServletRequest;


/**
 * 构建请求 headers
 * @author wangxiaoliang
 */
@SuppressWarnings("unchecked")
public class RequestAnalysor {

    /**
     * 获取请求头 key-value 集合
     *
     * @param request
     * @return
     */
    public static Map<String, String> headersToMap(HttpServletRequest request) {
        Map<String, String> headers = new HashMap<>();
        Enumeration<String> names = request.getHeaderNames();
        while (names.hasMoreElements()) {
            String key = names.nextElement();
            String value = request.getHeader(key);
            headers.put(key, value);
        }
        return headers;
    }

    /**
     * @param request
     * @param readbody 是否读取请求体中的参数,读取之后,该 request 的请求体将不存在
     * @return
     */
    public static Map<String, List<String>> parametersToMap(HttpServletRequest request, boolean readbody) {
        if (!readbody) {
            String url = request.getRequestURL().toString();
            int indexOf = url.indexOf("?");
            if (indexOf != -1) {
                String queryString = url.substring(indexOf);
                if (Objects.nonNull(queryString)) {
                    return argsAnslyse(queryString);
                }
            }
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * 从请求体中获取请求参数,当前情况特殊，x-www-urlencode 请求无法自动注入，网关当前仅一个本地接口是 x-www-urlencode 请求，新开发的应用不再兼容
     *
     * @param stream
     * @param clazz
     * @return
     */
    public static Map<String, List<String>> getParameters(HttpServletRequest request) {
        try {
            // 读取请求体
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(request.getInputStream(), baos);
            String s = new String(baos.toByteArray(), "UTF-8");
            // 分解参数
            return argsAnslyse(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.EMPTY_MAP;
    }

    /**
     * 参数分析
     *
     * @param queryString
     * @return
     */
    public static Map<String, List<String>> argsAnslyse(String queryString) {
        if (Objects.isNull(queryString)) {
            return Collections.EMPTY_MAP;
        }
        String name, value;
        List<String> list;
        HashMap<String, List<String>> mapA = new HashMap<String, List<String>>();
        StringTokenizer st = new StringTokenizer(queryString, "&");
        int i;
        while (st.hasMoreTokens()) {
            queryString = st.nextToken();
            i = queryString.indexOf("=");
            if (i > 0 && queryString.length() > i + 1) {
                name = queryString.substring(0, i);
                value = queryString.substring(i + 1);
                list = mapA.get(name);
                if (list == null) {
                    mapA.put(name, (list = new LinkedList<String>()));
                }
                list.add(value);
            }
        }
        return mapA;
    }

    /**
     * 请求调试信息
     *
     * @param request
     * @return
     */
    public static String getUri(HttpServletRequest request) {
        String queryString = request.getQueryString();
        return request.getMethod() + ":" + request.getRequestURI() + (StringUtils.isEmpty(queryString) ? "" : ("?" + queryString));
    }

    public String toStringUrl() {
        return null;
    }

    /**
     * 将 formData 数据还原成 queryString 类型数据
     *
     * @param parameters
     * @param formParam
     */
    public static String toQueryString(Map<String, String[]> formDataParam, HashMap<String, String[]> parameters) {
        StringBuilder builder = new StringBuilder();

        for (Entry<String, String[]> entry : formDataParam.entrySet()) {
            String key = entry.getKey();
            String[] values = entry.getValue();
            if (!parameters.containsKey(key)) {
                for (String value : values) {
                    builder.append(key).append("=").append(value).append("&");
                }
            }
        }

        return builder.length() != 0 ?
                builder.deleteCharAt(builder.length() - 1).toString() : "";
    }

}
